package com.sihan.framework.etm.service.baseData.impl;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.framework.mybatis.Condition;
import com.framework.util.JsonUtils;
import com.sihan.framework.etm.common.AppConfiguration;
import com.sihan.framework.etm.common.util.*;
import com.sihan.framework.etm.entity.DevicePush;
import com.sihan.framework.etm.entity.EtmDeviceRecord;
import com.sihan.framework.etm.entity.baseData.DeviceModel;
import com.sihan.framework.etm.enums.DeviceType;
import com.sihan.framework.etm.mapper.baseData.DeviceMapper;
import com.sihan.framework.etm.mapper.baseData.EtmDeviceRecordMapper;
import com.sihan.framework.etm.service.DevicePushService;
import com.sihan.framework.etm.service.EtmDeviceMountService;
import com.sihan.framework.etm.vo.ToolIocationMode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
@EnableAsync
public class ReceiveRecord {

    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private EtmDeviceRecordMapper etmDeviceRecordMapper;
    @Autowired
    private EtmDeviceMountService mountService;
    @Value("${guowang.isSendMsg}")
    private Boolean isSendMsg;
    @Autowired
    private DevicePushService devicePushService;

    @Autowired
    private AppConfiguration appConfig;


    @Async("taskExecutor")
    public void newReceiveRecord(ToolIocationMode mode, String data,Date date) {
        if (null == date){
            date = new Date();
        }
        try {
            String deviceCode = mode.getId();
            DeviceModel device = deviceMapper.selectOne(new Condition(new DeviceModel()).eq("communication_code", deviceCode).eq("is_delete", 0));
            BigDecimal lng = null;
            BigDecimal lnt = null;
            if (device != null) {
                BigDecimal electricityPercent = BigDecimal.ZERO;
                //米级定位：type=6001; BC20 通过发送次数计算电量
                //分米级定位：type=6002; RTK 通过电压计算电量  有三项挂接数据
                //安全帽：type=6003; 通过发送次数计算电量  有近电报警
                //警示牌：type=6004; 通过发送次数计算电量
                //警示牌－只测电压的警示牌：type=600５; 通过电压计算电量（）
                if (!"6002".equals(mode.getType())) {
                    //LocalDate now = LocalDate.now();
//                    LocalDate existSendDate = null == device.getSendNewTime() ? now :
//                            device.getSendNewTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
//
//                    if (device.getSendCount() > device.getSendCount() || null == device.getSendNewTime()) {
//                        device.setSendNewTime(new Date());
//                    }

                    //通过电压计算电量
                    electricityPercent = QuantityUtils.formattedQuantity(device.getVoltage());
                    //通过发送次数计算电量
                    //electricityPercent = QuantityUtils.calculateVoltage(device.getSendCount(), days.intValue());
                    if("6005".equals(mode.getType())){
                        //如果是６００５电压不同需要重新计算
                        String[] voltageRange = appConfig.getJinshipaiVoltageRange().split(";");
                        electricityPercent = QuantityUtils.formattedNewQuantity(device.getVoltage(),new BigDecimal(voltageRange[0]),new BigDecimal(voltageRange[1]));
                    }
                }
                Double longitude = Double.parseDouble(mode.getLongitude());
                Double latitude = Double.parseDouble(mode.getLatitude());
                if (longitude != 0 && latitude != 0){
                    String coorOld = longitude+","+latitude;
                    //判断是否是十进制度格式
                    if (!DecimalDegreeValidator.isRational(coorOld)){
                        coorOld = longitude / 1000000.00 + "," + latitude / 1000000.00;
                    }
                    try {
                        String coors = sgmap.coorTrans(coorOld);
                        // 创建 ObjectMapper 实例
                        ObjectMapper objectMapper = new ObjectMapper();
                        JsonNode rootNode = objectMapper.readTree(coors);
                        // 获取 "value" 数组
                        JsonNode valueArray = rootNode.path("value");
                        // 遍历数组并获取 x 和 y 的值
                        for (JsonNode item : valueArray) {
                            lng = item.path("x").decimalValue();
                            lnt = item.path("y").decimalValue();
                        }
                    } catch(Exception e) {
                        e.printStackTrace();
                    }

                    device.setInitialLat(lnt);
                    device.setInitialLng(lng);
                }
                if ("4001".equals(mode.getType())){
                    BigDecimal bigDecimal = new BigDecimal(mode.getHeight());
                    device.setInitialHeight(bigDecimal);
                }else if (Integer.parseInt(mode.getHeight()) > 0){
                    device.setInitialHeight(BigDecimal.valueOf(Integer.parseInt(mode.getHeight()) / 10.0));
                }
                EtmDeviceRecord record = EtmDeviceRecord.builder()
                        .deviceId(device.getId())
                        .deviceCode(deviceCode)
                        .type(mode.getType())
                        .rawData(data)
                        .createTime(date)
                        .electricityPercent(electricityPercent == null ? null : electricityPercent.doubleValue())
                        .alarm(Integer.parseInt(mode.getAlarm()))
                        .positionalAccuracy(Integer.parseInt(mode.getPrecision()))
                        .build();

                if (device.getTypeId().equals(DeviceType.SafetyHat)) {
                    if (device.getInitialLng() == null || device.getInitialLat() == null || device.getInitialHeight() == null) {
                        deviceMapper.updateById(device);
                        record.setPositionOffset((double) 0);
                    } else {

                        record.setPositionOffset(DistanceComputer.compute(
                                DistanceComputer.Point.builder()
                                        .height(device.getInitialHeight().doubleValue())
                                        .longitude(lng==null ? 0 : lng.doubleValue())
                                        .latitude(lnt==null ? 0 : lnt.doubleValue())
                                        .build(),
                                DistanceComputer.Point.builder()
                                        .height(Integer.parseInt(mode.getHeight()) / 10.0)
                                        .longitude(lng==null ? 0 : lng.doubleValue())
                                        .latitude(lnt==null ? 0 : lnt.doubleValue())
                                        .build()
                        ));
                    }
                }
                if (device.getTypeId().equals(DeviceType.GroundWire) || device.getTypeId().equals(DeviceType.SDGroundWire)) {
                    //处理三项数据
                    record.setHitchA(!("0".equals(mode.getA())));
                    record.setHitchB(!("0".equals(mode.getB())));
                    record.setHitchC(!("0".equals(mode.getC())));
                }
                if ("4001".equals(mode.getType())){
                    record.setG1(!("0".equals(mode.getD1())));
                    record.setG2(!("0".equals(mode.getD2())));
                    record.setG3(!("0".equals(mode.getD3())));
                    BigDecimal height = new BigDecimal(mode.getHeight());
                    BigDecimal geoSep = new BigDecimal(mode.getGeo_sep());
                    BigDecimal geodeticHeight = height.subtract(geoSep).setScale(2, RoundingMode.HALF_UP);
                    record.setGeodeticHeight(geodeticHeight);
                }
                if (device.getTypeId().equals(DeviceType.WarningSign)) {
                    //处理三项数据
                    String a = mode.getA();
                    if ("1".equals(a) && 1 == record.getAlarm()) {
                        mountService.insertDeviceMount(record, device,date);
                    }
                    if ("1".equals(a)) {
                        record.setAlarm(422);
                    }

                }
                record.setRawData(mode.toStr(date));
                deviceMapper.updateById(device);
                //根据 record 与 device 做工器具状态 做记录
                mountService.insertDeviceMount(record, device,date);
                etmDeviceRecordMapper.insert(record);
                //判断是否是新疆的设备 是否推送
                if("a6a5f3be8a0240c48590cd0099107a7a".equals(device.getOrgId()) && isSendMsg){
                    ToolIocationMode mode1 = JsonUtils.readFromJson(data, ToolIocationMode.class);
                    SendGuoWang.sendMsg(mode1.toStr(date),DateUtils.getInstance().getDateStr(date, DateUtils.getInstance().SDF_HH),mode1.getId());
                }
                //判断是否需要推送到检测机构
                DevicePush devicePush = devicePushService.selectByDeviceId(device.getId());
                if (devicePush!= null && devicePush.getState()){
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("deviceId",record.getDeviceCode());
                    jsonObject.put("let",mode.getLatitude());
                    jsonObject.put("lng",mode.getLongitude());
                    jsonObject.put("positional",record.getPositionalAccuracy());
                    jsonObject.put("satellite",mode.getSatellite());
                    jsonObject.put("voltage",(String.format("%.2f",Double.parseDouble(mode.getVoltage()) / 100)));
                    jsonObject.put("time",date);
                    Map<String, String> headers = new HashMap<>();
                    headers.put("Content-Type", "application/json");
                    String s = HttpUtil.httpPostJson(devicePush.getPushSite(), jsonObject.toJSONString(), headers);
                    log.info("===推送检测机构反馈{}",s);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
